Skip to content

feat: Sequencing workflows so that faster workflows run before slower ones#4670

Merged
denis256 merged 1 commit intomainfrom
chore/cleaning-up-ci
Aug 15, 2025
Merged

feat: Sequencing workflows so that faster workflows run before slower ones#4670
denis256 merged 1 commit intomainfrom
chore/cleaning-up-ci

Conversation

@yhakbar
Copy link
Copy Markdown
Collaborator

@yhakbar yhakbar commented Aug 14, 2025

Description

Sequences workflows so that we're not running slow workflows if we have to push again anyways.

TODOs

Read the Gruntwork contribution guidelines.

  • I authored this code entirely myself
  • I am submitting code based on open source software (e.g. MIT, MPL-2.0, Apache)]
  • I am adding or upgrading a dependency or adapted code and confirm it has a compatible open source license
  • Update the docs.
  • Run the relevant tests successfully, including pre-commit checks.
  • Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

Added / Removed / Updated [X].

Migration Guide

Summary by CodeRabbit

  • Chores
    • Converted existing automation workflows to reusable ones, now invoked by a centralized CI pipeline.
    • Introduced a new CI workflow that orchestrates linting, pre-commit checks, spell-checking, markdown linting, license checks, builds (with and without proxy), and integration tests (including OIDC), with explicit job ordering.
    • Preserved existing job logic and steps; workflows no longer run automatically on push but via the CI orchestrator.
    • No changes to product functionality or public interfaces.

@vercel
Copy link
Copy Markdown

vercel bot commented Aug 14, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
terragrunt-docs Ready Preview Comment Aug 14, 2025 6:10pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Aug 14, 2025

📝 Walkthrough

Walkthrough

Converted multiple GitHub Actions workflows from push-triggered to reusable (workflow_call). Added a new CI workflow that triggers on push and orchestrates the reusable workflows with dependencies across linting, checks, builds, and integration tests, including an OIDC variant.

Changes

Cohort / File(s) Summary of Changes
Reusable workflow conversion (workflow_call)
.github/workflows/base-test.yml, .github/workflows/build-no-proxy.yml, .github/workflows/build.yml, .github/workflows/codespell.yml, .github/workflows/integration-test.yml, .github/workflows/license-check.yml, .github/workflows/lint.yml, .github/workflows/markdownlint.yml, .github/workflows/oidc-integration-test.yml, .github/workflows/precommit.yml
Changed trigger from push to workflow_call; job logic and steps unchanged.
New CI orchestrator
.github/workflows/ci.yml
Added CI workflow triggered on push; invokes reusable workflows (lint, precommit, codespell, markdownlint, license_check) and then base tests, builds, and integration tests (including OIDC) via needs and uses; secrets inherited; appropriate permissions set.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Dev as Developer
    participant GH as GitHub Actions (CI)
    participant L as lint.yml
    participant P as precommit.yml
    participant C as codespell.yml
    participant M as markdownlint.yml
    participant LC as license-check.yml
    participant BT as base-test.yml
    participant B as build.yml
    participant BNP as build-no-proxy.yml
    participant IT as integration-test.yml
    participant OIDC as oidc-integration-test.yml

    Dev->>GH: push
    GH->>L: uses (workflow_call)
    GH->>P: uses (workflow_call)
    GH->>C: uses (workflow_call)
    GH->>M: uses (workflow_call)
    GH->>LC: uses (workflow_call)

    par After checks complete
        GH->>BT: uses (needs: L,P,C,M,LC)
        GH->>B: uses (needs: L,P,C,M,LC)
        GH->>BNP: uses (needs: L,P,C,M,LC)
    end

    GH->>IT: uses (needs: BT,B,BNP)
    GH->>OIDC: uses (needs: BT,B,BNP) with id-token: write
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related PRs

Suggested reviewers

  • denis256
  • levkohimins

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/cleaning-up-ci

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@yhakbar yhakbar marked this pull request as ready for review August 14, 2025 18:13
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🔭 Outside diff range comments (11)
.github/workflows/lint.yml (2)

11-21: Pin all third-party actions to immutable commit SHAs

To eliminate floating tags and reduce supply-chain risk, replace every @vX reference with the corresponding full commit SHA.

In .github/workflows/lint.yml:

  • Line 11: uses: actions/checkout@v4
  • Line 14: uses: jdx/mise-action@v2
  • Lines 31, 37, 43: uses: actions/cache@v4

Suggested diff pattern:

- uses: actions/checkout@v4
+ uses: actions/checkout@<commit-SHA_for_v4>

- uses: jdx/mise-action@v2
+ uses: jdx/mise-action@<commit-SHA_for_v2>

- uses: actions/cache@v4
+ uses: actions/cache@<commit-SHA_for_v4>

You can look up the latest SHAs on each repo’s “Releases” or “Tags” page:
https://github.com/actions/checkout/tags/v4
https://github.com/actions/cache/tags/v4
https://github.com/jdx/mise-action/tags/v2


22-46: Add a workflow input for the golangci-lint cache path and correct the output name

The reusable workflow currently hard-codes the golangci-lint cache path and misspells the output key. To fix:

  1. Under on.workflow_call, declare an optional input for the cache path with a sensible default.
  2. In the go-cache-paths step, rename “golanci-lint-cache” to “golangci-lint-cache” and emit the value from the new input.
  3. Update the cache step to reference the corrected output name.

Suggested diff:

 .github/workflows/lint.yml

 on:
-  workflow_call:
+  workflow_call:
+    inputs:
+      golangci_lint_cache_path:
+        description: Path to golangci-lint cache directory
+        required: false
+        default: /home/runner/.cache/golangci-lint

 jobs:
   lint:
     runs-on: ubuntu-latest

     steps:
@@
     - id: go-cache-paths
       run: |
-        # TODO: Make this less brittle.
-        echo "golanci-lint-cache=/home/runner/.cache/golangci-lint" >> "$GITHUB_OUTPUT"
+        # Cache path for golangci-lint (configurable via workflow input)
+        echo "golangci-lint-cache=${{ inputs.golangci_lint_cache_path }}" >> "$GITHUB_OUTPUT"
@@
     - name: golangci-lint Cache
       uses: actions/cache@v4
       with:
-        path: ${{ steps.go-cache-paths.outputs.golanci-lint-cache }}
+        path: ${{ steps.go-cache-paths.outputs.golangci-lint-cache }}
         key: ${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.sum') }}-linux-amd64
  • Defines golangci_lint_cache_path under workflow_call.inputs
  • Fixes the typo from golanci-lint-cachegolangci-lint-cache
  • Makes the cache path configurable to avoid brittle, hard-coded Linux home paths
.github/workflows/markdownlint.yml (2)

14-19: Broaden default globs and allow override via input.

Currently only docs/**/*.md is linted; top-level README and other Markdown outside docs are skipped.

       - name: Run markdownlint
         uses: DavidAnson/markdownlint-cli2-action@v20
         with:
-          globs: |
-            docs/**/*.md
+          globs: ${{ inputs.globs || '**/*.md' }}

11-15: Pin Actions to Immutable SHAs
To prevent unexpected breakages from tag updates, please replace the mutable tags with full commit SHAs in .github/workflows/markdownlint.yml (around lines 11–15):

• Replace

uses: actions/checkout@v4
uses: DavidAnson/markdownlint-cli2-action@v20

with something like

- uses: actions/checkout@v4
+ uses: actions/checkout@<checkout-commit-sha>
- uses: DavidAnson/markdownlint-cli2-action@v20
+ uses: DavidAnson/markdownlint-cli2-action@<markdownlint-commit-sha>

I can follow up with a PR that pins these to the exact SHAs.

.github/workflows/build.yml (1)

28-66: Pin Actions to Specific SHAs and Add Job Timeout

To prevent accidental breakage from upstream updates and avoid indefinite hangs, pin each action to its full commit SHA and set a timeout for the build job.

• Pin the following actions:
– actions/checkout@v4 → 08eba0b27e820071cde6df949e0beb9ba4906955
– jdx/mise-action@v2 → c37c93293d6b742fc901e1406b8f764f6fb19dac
– actions/cache@v4 → 0400d5f644dc74513175e3cd8d07132dd4860809
– actions/upload-artifact@v4 → ea165f8d65b6e75b540449e92b4886f43607fa02

• Add a 15-minute timeout to the build job.

Suggested patch (in .github/workflows/build.yml):

 jobs:
   build:
+    timeout-minutes: 15
     strategy:
       matrix:
         os: [linux, windows]
         arch: [amd64, arm64]

     steps:
       - name: Checkout code
-        uses: actions/checkout@v4
+        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955

       - name: Use mise to install dependencies
-        uses: jdx/mise-action@v2
+        uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac
         with:
           version: 2025.4.4
           experimental: true

       - id: go-cache-paths
         run: |
           echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"

       - name: Go Build Cache
-        uses: actions/cache@v4
+        uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809
         with:
           path: ${{ steps.go-cache-paths.outputs.go-build }}
           key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}

       - name: Upload Build Artifact
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
         with:
           name: terragrunt_${{ matrix.os }}_${{ matrix.arch }}
.github/workflows/integration-test.yml (3)

218-228: Avoid potential secret leakage; keep xtrace off or sanitize.

You source an env file that may contain secrets, then enable set -x (xtrace). While your go test command doesn’t expand secrets directly, xtrace sometimes leaks values if used in future changes or commands. Safer to avoid xtrace or to redact.

-            # print command arguments
-            set -x
+            # print command arguments minimally; avoid xtrace to prevent accidental secret leakage
+            set -o nounset -o errexit -o pipefail

Alternatively, use a wrapper that filters sensitive env on print.


163-189: Restrict permissions on the generated .env.secrets file

Verified that generate-secrets.sh only writes secrets into $ENV_FILE and the only stdout message is the benign status echo. However, it never tightens filesystem permissions, so the file may be world-readable by default.

Please update .github/scripts/setup/generate-secrets.sh to set restrictive permissions (e.g. 0600) after writing the secrets:

 echo "Created environment file with secrets for $NAME"
+chmod 0600 "$ENV_FILE"

This ensures no unintended users can read the secrets file.


151-171: Pin Actions to Commit SHAs and Add a Job Timeout

To prevent unexpected breaking changes and ensure this long‐running job can’t hang indefinitely:

• Replace version tags with full commit SHAs for each referenced action in .github/workflows/integration-test.yml
– Line 153: actions/checkout@v4actions/checkout@<SHA>
– Line 165: jdx/mise-action@v2jdx/mise-action@<SHA>
– Line 240: actions/upload-artifact@v4actions/upload-artifact@<SHA>
– Line 246: mikepenz/action-junit-report@v5mikepenz/action-junit-report@<SHA>

• Add a sane timeout-minutes at the job level (same indentation as runs-on) to guard against runaway integration tests. For example:

jobs:
  integration-test:
    runs-on: ubuntu-latest
    timeout-minutes: 60
    steps:
      

Let me know if you’d like me to stage a PR with the exact SHAs and timeout value.

.github/workflows/build-no-proxy.yml (1)

51-64: Ensure output directory exists; build currently risks failing with “no such file or directory”.

go build -o doesn’t create parent directories. If bin/ doesn’t exist, the build will fail.

Apply:

       - name: Build Terragrunt without Go proxy
         env:
           GOPROXY: direct
           GOOS: ${{ matrix.os }}
           GOARCH: ${{ matrix.arch }}
         run: |
           OUTPUT="bin/terragrunt-${GOOS}-${GOARCH}"
           if [ "${GOOS}" = "windows" ]; then
             OUTPUT="${OUTPUT}.exe"
           fi
+          mkdir -p "$(dirname "${OUTPUT}")"
           go build -o "${OUTPUT}" \
             -ldflags "-X github.com/gruntwork-io/go-commons/version.Version=${GITHUB_REF_NAME} -extldflags '-static'" \
             .
.github/workflows/oidc-integration-test.yml (2)

38-44: Fix potential hang: docker builder prune missing --force.

docker builder prune -a prompts for confirmation without -f, which can hang the job.

Apply:

           sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
           sudo docker image prune --all --force
-          sudo docker builder prune -a
+          sudo docker builder prune -a --force
           df -h

101-111: Make artifacts/report robust when tests are skipped.

When SKIP=true, result.xml isn’t created. Uploading artifacts and generating the report may warn/fail. Make uploads conditional and ignore missing files; keep the summary display.

Apply:

       - name: Upload Report (${{ matrix.integration.name }})
+        if: always()
         uses: actions/upload-artifact@v4
         with:
           name: test-report-${{ matrix.integration.name }}
           path: result.xml
+          if-no-files-found: ignore

       - name: Display Test Results (${{ matrix.integration.name }})
         uses: mikepenz/action-junit-report@v5
         if: always()
         with:
           report_paths: result.xml
           detailed_summary: 'true'
           include_time_in_summary: 'true'
           group_suite: 'true'

Also applies to: 122-127, 128-136

🧹 Nitpick comments (11)
.github/workflows/lint.yml (1)

31-41: Improve cache key specificity across architectures.

Keys end with a hard-coded linux-amd64. Prefer ${{ runner.arch }} to prevent cache mismatches and improve hit rates if GitHub changes runner arch.

-        key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-linux-amd64
+        key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ runner.arch }}
@@
-        key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-linux-amd64
+        key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-${{ runner.arch }}
@@
-        key: ${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.sum') }}-linux-amd64
+        key: ${{ runner.os }}-golangci-lint-${{ hashFiles('**/go.sum') }}-${{ runner.arch }}
.github/workflows/base-test.yml (2)

36-46: Cache key uses hard-coded arch; switch to runner.arch.

On macOS, GitHub-hosted runners can be arm64. Using -amd64 reduces cache hit quality and can cause subtle issues.

-          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
+          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ runner.arch }}
@@
-          key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-amd64
+          key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ runner.arch }}

6-16: Consider adding job-level timeout for extra safety.

You already set -timeout 45m for go test; also add timeout-minutes: 60 at the job level to prevent stuck runners.

.github/workflows/build.yml (2)

40-49: Improve cache keys to consider runner architecture.

Avoid generic keys that could mismatch across runner architectures.

-          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}
+          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}-${{ runner.arch }}

69-145: Mac signing job: pin actions, cache gon by checksum, and consider artifact retention.

  • Pin actions/checkout@v4, actions/download-artifact@v4, actions/upload-artifact@v4 to SHAs.
  • Cache gon using its download URL checksum to avoid stale tool when GON_VERSION changes without cache key update.
  • Optionally set retention-days on upload-artifact.

Example changes (non-diff snippet):

- uses: actions/cache@v4
  with:
    path: gon
    key: gon-${{ env.GON_VERSION }}-${{ hashFiles('.github/workflows/build.yml') }}

- uses: actions/upload-artifact@v4
  with:
    name: signed-files
    path: bin/*
    retention-days: 7
.github/workflows/integration-test.yml (1)

207-217: Cache key uses hard-coded arch; prefer runner.arch.

-          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.integration.os }}-amd64
+          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.integration.os }}-${{ runner.arch }}
.github/workflows/precommit.yml (2)

36-43: Drop unnecessary pre-commit install to speed up CI.

Installing git hooks in CI is redundant; running the hooks directly is sufficient.

Apply:

       - name: Run pre-commit hooks
         env:
           GOPROXY: direct
           GOOS: linux
           GOARCH: amd64
         run: |
-          pre-commit install
           pre-commit run --all-files

26-35: Optional: cache Go modules for faster hooks.

If any hooks do go builds/tests, also caching GOMODCACHE (module download cache) can reduce runtime.

Example:

       - id: go-cache-paths
         run: |
           echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
+          echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"

       - name: Go Build Cache
         uses: actions/cache@v4
         with:
-          path: ${{ steps.go-cache-paths.outputs.go-build }}
-          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-linux-amd64
+          path: |
+            ${{ steps.go-cache-paths.outputs.go-build }}
+            ${{ steps.go-cache-paths.outputs.go-mod }}
+          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}-linux-amd64
.github/workflows/codespell.yml (1)

15-21: Verify codespell compatibility with Python 3.13, or pin to a known-supported version.

You’re pinning codespell==2.4.0 and using Python 3.13.3 via mise. Confirm that this codespell version supports Python 3.13. If not, either:

  • Use Python 3.12.x, or
  • Bump codespell to a version that supports 3.13, or
  • Install with pipx.

I can check upstream compatibility if needed. Would you like me to run a quick web check?

Optional change (pin Python 3.12):

         with:
           version: 2025.4.4
           experimental: true
           mise_toml: |
             [tools]
-            python = "3.13.3"
+            python = "3.12.5"

Also applies to: 23-31, 35-36

.github/workflows/build-no-proxy.yml (2)

51-56: Optional: consider CGO_ENABLED=0 for more reliable cross-compiles.

Static and cross-compiles (darwin/windows/linux 386) can fail if CGO is inadvertently enabled. Setting CGO_ENABLED=0 improves portability.

       - name: Build Terragrunt without Go proxy
         env:
           GOPROXY: direct
           GOOS: ${{ matrix.os }}
           GOARCH: ${{ matrix.arch }}
+          CGO_ENABLED: 0

41-49: Optional: also cache GOMODCACHE for faster dependency resolution.

You’re caching only GOCACHE. Caching the module download cache can significantly speed up builds.

       - id: go-cache-paths
         run: |
           echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
+          echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"

       - name: Go Build Cache
         uses: actions/cache@v4
         with:
-          path: ${{ steps.go-cache-paths.outputs.go-build }}
-          key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}
+          path: |
+            ${{ steps.go-cache-paths.outputs.go-build }}
+            ${{ steps.go-cache-paths.outputs.go-mod }}
+          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}-${{ matrix.os }}-${{ matrix.arch }}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a43b30a and 5b2186e.

📒 Files selected for processing (11)
  • .github/workflows/base-test.yml (1 hunks)
  • .github/workflows/build-no-proxy.yml (1 hunks)
  • .github/workflows/build.yml (1 hunks)
  • .github/workflows/ci.yml (1 hunks)
  • .github/workflows/codespell.yml (1 hunks)
  • .github/workflows/integration-test.yml (1 hunks)
  • .github/workflows/license-check.yml (1 hunks)
  • .github/workflows/lint.yml (1 hunks)
  • .github/workflows/markdownlint.yml (1 hunks)
  • .github/workflows/oidc-integration-test.yml (1 hunks)
  • .github/workflows/precommit.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: build / Sign Binaries
  • GitHub Check: build_no_proxy / Build (windows/386)
  • GitHub Check: build_no_proxy / Build (linux/386)
  • GitHub Check: build_no_proxy / Build (darwin/arm64)
  • GitHub Check: build_no_proxy / Build (windows/amd64)
  • GitHub Check: build_no_proxy / Build (linux/arm64)
  • GitHub Check: build_no_proxy / Build (linux/amd64)
  • GitHub Check: build_no_proxy / Build (darwin/amd64)
  • GitHub Check: base_tests / Test (ubuntu)
  • GitHub Check: base_tests / Test (macos)
  • GitHub Check: build-and-test
🔇 Additional comments (11)
.github/workflows/base-test.yml (1)

48-57: go-junit-report is already provisioned by the mise step

  • The workflow’s “Use mise to install dependencies” step (lines 21–25 in .github/workflows/base-test.yml) reads mise.cicd.toml.
  • In mise.cicd.toml, you have go-junit-report = "2.1.0" configured, so go-junit-report will be installed before running tests.
  • No extra installation step is needed.
.github/workflows/precommit.yml (1)

3-5: Reusable workflow conversion looks good; ensure the orchestrator sequences and inherits secrets.

Switching to workflow_call is correct for central orchestration. Please confirm the new CI orchestrator:

  • Calls this workflow with needs to sequence fast jobs ahead of slow ones.
  • Uses secrets: inherit so the GITHUB_TOKEN is available to mise and pre-commit.

I can auto-verify ci.yml usage if you share it.

.github/workflows/codespell.yml (1)

3-5: Reusable workflow conversion is correct; verify orchestrator invocation.

Ensure the new CI invokes this via uses and includes secrets: inherit so GITHUB_TOKEN is available to mise.

.github/workflows/build-no-proxy.yml (1)

3-5: Confirm sequencing in the parent CI workflow.

This job is a slow, multi-matrix build. Validate that the orchestrating workflow runs it only after faster checks (lint, pre-commit, codespell) pass via needs to achieve the PR objective.

.github/workflows/oidc-integration-test.yml (2)

7-9: Reusable workflow conversion is fine; ensure caller passes permissions and secrets.

OIDC requires id-token: write and relevant cloud secrets. Verify the calling CI workflow:

  • Grants permissions: id-token: write for the job that uses this reusable workflow.
  • Uses secrets: inherit (or passes explicit secrets).

I can scan ci.yml automatically if you’d like.


46-54: Request: verify go-junit-report availability and PATH.

The pipeline pipes go test output into go-junit-report, but there’s no explicit install here. Presumably mise sets it up. Please confirm mise.toml (or previous setup) ensures go-junit-report is installed and in PATH.

Also applies to: 90-100, 101-111

.github/workflows/license-check.yml (2)

3-5: Reusable workflow conversion LGTM; confirm orchestrator passes secrets.

This job requires GITHUB_TOKEN for make license-check. Ensure the caller uses secrets: inherit.


25-33: Nice use of pipefail to preserve failure status.

The make | tee pattern won’t mask failures due to set -o pipefail. Good attention to CI correctness.

.github/workflows/ci.yml (3)

7-26: Nice sequencing: fast checks gate slower stages

The use of needs to gate base tests and builds on quick checks achieves the PR goal of sequencing and prevents wasteful long runs on failing quick checks.

Also applies to: 27-44


53-60: OIDC permission placement looks correct for local reusables

Setting id-token: write at the caller job level is the right way to enable OIDC in a locally reused workflow. No change needed.


1-63: Heads-up: Required status check contexts have changed
Moving all jobs under the single “CI” workflow will rename your status checks from, for example,
• “lint” → “CI / lint”
• “build” → “CI / build”
• “integration_tests” → “CI / integration_tests”

If you have branch protection rules that enforce required status checks on main (or any protected branch), you will need to update those contexts or merges will be blocked.

Action items:

  • In your repo’s Settings → Branches → Branch protection, edit the rule for your protected branch.
  • Under Require status checks to pass before merging, remove the old names and add the new contexts (e.g., “CI / lint”, “CI / build”, “CI / integration_tests”, etc.).
  • Save your changes and confirm that all new checks are passing.

Comment on lines 3 to 5
on:
push:
workflow_call:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reusable workflow conversion looks good; declare inputs and permissions.

Define inputs (e.g., OS matrix override, test timeout) and least-privilege permissions. This formalizes the contract and improves security.

 on:
-  workflow_call:
+  workflow_call:
+    inputs:
+      os:
+        description: 'Space-separated OS list (e.g., "ubuntu macos")'
+        required: false
+        type: string
+      timeout_minutes:
+        description: 'go test timeout in minutes'
+        required: false
+        type: number
+    secrets: {}

Then add (outside selected range):

permissions:
  contents: read
🤖 Prompt for AI Agents
In .github/workflows/base-test.yml around lines 3 to 5, the reusable workflow is
missing declared inputs and least-privilege permissions; add a workflow_call
inputs block (for example inputs like os_matrix_override, test_timeout,
node_version or others your consumers need) directly under workflow_call to
formalize the contract, and add a top-level permissions block (e.g.,
permissions: contents: read) at the file root to enforce least-privilege access;
ensure input names, types and defaults are reasonable and documented in the file
so callers can override them.

Comment on lines 3 to 5
on:
push:
workflow_call:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reusable conversion approved; expose inputs for matrix control and set permissions.

Allow the orchestrator to pass a subset of OS/arch to shorten slow builds when not needed.

 on:
-  workflow_call:
+  workflow_call:
+    inputs:
+      matrix_include:
+        description: 'YAML/JSON list for matrix.include (os/arch pairs)'
+        required: false
+        type: string
+    secrets: {}

Then, adapt the matrix to read from input when provided (outside the selected range):

strategy:
  matrix:
    include: ${{ inputs.matrix_include && fromJSON(inputs.matrix_include) || matrix.include }}

Also add:

permissions:
  contents: read
🤖 Prompt for AI Agents
In .github/workflows/build.yml around lines 3 to 5, the reusable workflow does
not expose inputs for controlling the OS/arch matrix nor set repository
permissions; add inputs for matrix control (e.g., matrix_include as a string)
under workflow_call so the orchestrator can pass a JSON subset, then update the
job strategy matrix to prefer the input when present (use the conditional:
include: ${{ inputs.matrix_include && fromJSON(inputs.matrix_include) ||
matrix.include }}), and add permissions: contents: read at the top-level of the
workflow so the reusable workflow has read access to repository contents.

Comment on lines +3 to +6
on:
push:

jobs:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add pull_request + workflow_dispatch triggers, default least-privilege permissions, and cancel-in-progress concurrency

This centralizes CI while ensuring PRs run, manual runs are possible, and redundant in-flight runs are canceled on new pushes to the same ref. Also sets minimal default GITHUB_TOKEN permissions.

Apply:

 name: CI

-on:
-  push:
+on:
+  push:
+  pull_request:
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+concurrency:
+  group: ci-${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 3-6, the workflow only triggers on push
and lacks least-privilege default permissions and concurrency control; update
the top-level YAML to include on: push, pull_request, and workflow_dispatch
triggers, add a minimal default permissions block (for example permissions:
contents: read, packages: read — adjust if your jobs need more), and add a
concurrency block (group: ${{ github.workflow }}-${{ github.ref }},
cancel-in-progress: true) so manual runs are possible, PRs trigger CI, runs use
least privilege, and in-flight runs for the same ref are cancelled.

Comment on lines +7 to +26
lint:
uses: ./.github/workflows/lint.yml
secrets: inherit

precommit:
uses: ./.github/workflows/precommit.yml
secrets: inherit

codespell:
uses: ./.github/workflows/codespell.yml
secrets: inherit

markdownlint:
uses: ./.github/workflows/markdownlint.yml
secrets: inherit

license_check:
uses: ./.github/workflows/license-check.yml
secrets: inherit

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify all referenced reusable workflows are switched to workflow_call and inputs/secrets match

Given the conversion, ensure each callee has on: workflow_call and that any required inputs match (none provided here). This avoids silent dispatch failures.

Also applies to: 27-44, 45-60


🏁 Script executed:

#!/bin/bash
set -euo pipefail

files=(
  ".github/workflows/lint.yml"
  ".github/workflows/precommit.yml"
  ".github/workflows/codespell.yml"
  ".github/workflows/markdownlint.yml"
  ".github/workflows/license-check.yml"
  ".github/workflows/base-test.yml"
  ".github/workflows/build.yml"
  ".github/workflows/build-no-proxy.yml"
  ".github/workflows/integration-test.yml"
  ".github/workflows/oidc-integration-test.yml"
)

echo "Checking reusable workflow configuration..."
for f in "${files[@]}"; do
  if [[ ! -f "$f" ]]; then
    echo "MISSING: $f"
    continue
  fi
  echo "---- $f"
  rg -n "^\s*on:\s*workflow_call" "$f" || echo "WARNING: $f is not configured with on: workflow_call"
  echo "Declared inputs (if any):"
  rg -n "^\s*inputs:" -n "$f" -A 50 | sed '/^\s*outputs:/,$d' || true
  echo
done

echo "If any workflow declares required inputs, add a with: { ... } block to the corresponding job in ci.yml."

Length of output: 6429


Add on: workflow_call to all referenced reusable workflows

All of the workflows invoked from ci.yml currently lack a workflow_call trigger. To ensure they can be dispatched without silent failures, each of the following files must begin with:

on:
  workflow_call:
    # define inputs here if the workflow requires any

• .github/workflows/lint.yml
• .github/workflows/precommit.yml
• .github/workflows/codespell.yml
• .github/workflows/markdownlint.yml
• .github/workflows/license-check.yml
• .github/workflows/base-test.yml
• .github/workflows/build.yml
• .github/workflows/build-no-proxy.yml
• .github/workflows/integration-test.yml
• .github/workflows/oidc-integration-test.yml

Since none of these declare required inputs, no with: blocks are currently needed in ci.yml. If you later add inputs to any reusable workflow, remember to pass them in the corresponding job’s with: section.

Comment on lines +45 to +52
integration_tests:
needs: [base_tests, build, build_no_proxy]
uses: ./.github/workflows/integration-test.yml
permissions:
contents: read
checks: write
secrets: inherit

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

Guard integration tests on forked PRs and set a timeout

Secrets are not available to workflows on pull_request from forks. Guard to skip instead of fail, and add a sensible timeout to avoid hung runs.

   integration_tests:
     needs: [base_tests, build, build_no_proxy]
+    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
     uses: ./.github/workflows/integration-test.yml
     permissions:
       contents: read
       checks: write
+    timeout-minutes: 90
     secrets: inherit

If your integration tests are expected to run on forked PRs (without secrets), reply and I can propose a paths-filter + conditional to only run a non-secret subset. Otherwise, verify the skip behavior matches expectations.


Guard integration tests on forked PRs and add a timeout

Integration tests rely on inherited secrets, which are not available for workflows triggered by pull_request from forked repos—causing failures. Skip the job for forked PRs and set a sensible timeout to prevent hung runs:

• File: .github/workflows/ci.yml (lines 45–52)
• Replace with:

 integration_tests:
   needs: [base_tests, build, build_no_proxy]
+  if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
   uses: ./.github/workflows/integration-test.yml
   permissions:
     contents: read
     checks: write
+  timeout-minutes: 90
   secrets: inherit

If you still need to run a subset of integration tests on forked PRs (without secrets), let me know and I can suggest a conditional paths filter. Otherwise, please apply this guard to avoid broken or hung CI runs.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
integration_tests:
needs: [base_tests, build, build_no_proxy]
uses: ./.github/workflows/integration-test.yml
permissions:
contents: read
checks: write
secrets: inherit
integration_tests:
needs: [base_tests, build, build_no_proxy]
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
uses: ./.github/workflows/integration-test.yml
permissions:
contents: read
checks: write
timeout-minutes: 90
secrets: inherit
🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 45 to 52, the integration_tests job
must be skipped for pull requests from forked repos and have a timeout to avoid
hanging; add an if condition to only run when the event is not a pull_request or
the pull_request head repo matches the current repository (use: if:
github.event.pull_request == null ||
github.event.pull_request.head.repo.full_name == github.repository) and add a
timeout-minutes value (e.g., timeout-minutes: 60) under the job definition so
the workflow exits after a sensible period.

Comment on lines +53 to +60
oidc_integration_tests:
needs: [base_tests, build, build_no_proxy]
uses: ./.github/workflows/oidc-integration-test.yml
permissions:
id-token: write
contents: read
checks: write
secrets: inherit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Guard OIDC integration tests on forked PRs and set a timeout

Same motivation as the non-OIDC integration suite. Keeps forks green without exposing secrets and avoids hangs.

   oidc_integration_tests:
     needs: [base_tests, build, build_no_proxy]
+    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
     uses: ./.github/workflows/oidc-integration-test.yml
     permissions:
       id-token: write
       contents: read
       checks: write
+    timeout-minutes: 90
     secrets: inherit

🏁 Script executed:

#!/bin/bash
set -e
echo "Searching in ci.yml for non-OIDC integration_tests job"
rg -n "integration_tests:" .github/workflows/ci.yml || true

echo
echo "Searching for timeout-minutes usage across all workflow files"
rg -n "timeout-minutes" .github/workflows || true

Length of output: 422


🏁 Script executed:

#!/bin/bash
set -e
echo "Showing lines around the non-OIDC integration_tests job for context"
rg -n -C5 "integration_tests:" .github/workflows/ci.yml

Length of output: 812


Guard OIDC integration tests on forked PRs and set a timeout

Same motivation as the non-OIDC integration suite: keeps forks green without exposing secrets and prevents hung jobs.

• File: .github/workflows/ci.yml
Job: oidc_integration_tests (lines 53–60)

Suggested diff:

   oidc_integration_tests:
     needs: [base_tests, build, build_no_proxy]
+    if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
     uses: ./.github/workflows/oidc-integration-test.yml
     permissions:
       id-token: write
       contents: read
       checks: write
+    timeout-minutes: 90
     secrets: inherit

This will skip OIDC tests on forked PRs and fail any run exceeding 90 minutes.

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 53 to 60, the oidc_integration_tests
job must be skipped for forked PRs and bounded to 90 minutes; update the job to
include an if guard that only runs when not a pull_request from a fork (for
example: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository) and add
timeout-minutes: 90 to the job definition so any run longer than 90 minutes will
fail.

Comment on lines 3 to 5
on:
push:
workflow_call:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reusable conversion looks good; explicitly declare required secrets and inputs.

This workflow consumes many secrets via the setup and test steps. Make the requirements explicit to prevent accidental silent failures at call time and to document contract.

 on:
-  workflow_call:
+  workflow_call:
+    inputs:
+      include_matrix:
+        description: 'Subset of integrations to run (JSON/YAML list of matrix entries)'
+        required: false
+        type: string
+    secrets:
+      GHA_DEPLOY_KEY:
+        required: false
+      AWS_ACCESS_KEY_ID:
+        required: false
+      AWS_SECRET_ACCESS_KEY:
+        required: false
+      AWS_TEST_OIDC_ROLE_ARN:
+        required: false
+      GCLOUD_SERVICE_KEY:
+        required: false
+      GOOGLE_CLOUD_PROJECT:
+        required: false
+      GOOGLE_COMPUTE_ZONE:
+        required: false
+      GOOGLE_IDENTITY_EMAIL:
+        required: false
+      GOOGLE_PROJECT_ID:
+        required: false
+      GCLOUD_SERVICE_KEY_IMPERSONATOR:
+        required: false
+      AWS_TEST_S3_ASSUME_ROLE:
+        required: false

Add least-privilege permissions (outside selected range). If any test uses OIDC, add id-token: write for that job only:

permissions:
  contents: read
  # id-token: write  # enable only if OIDC tests are run in this workflow
🤖 Prompt for AI Agents
In .github/workflows/integration-test.yml around lines 3 to 5, the reusable
workflow does not explicitly declare the required inputs/secrets or
least-privilege permissions, which can lead to silent failures when called;
update the workflow metadata to add an inputs and secrets section enumerating
every secret and required input the steps use (with descriptions and required:
true where applicable) and add a permissions block granting only needed scopes
(for example contents: read) and document/comment that id-token: write should be
added only for the job that uses OIDC; ensure the inputs/secrets names match
callers and update README/docs if needed.

Comment on lines 3 to 5
on:
push:
workflow_call:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Good conversion to a reusable workflow; consider formalizing inputs/secrets and least-privilege permissions.

Switching to workflow_call is correct. To make this reusable workflow more robust and self-documenting, define explicit inputs/secrets and set minimal permissions. This clarifies the contract for callers and tightens security.

Apply this diff to expand workflow_call with optional inputs (example) and declare no required secrets for now:

 on:
-  workflow_call:
+  workflow_call:
+    inputs:
+      go_version:
+        description: 'Go toolchain version (mise will resolve)'
+        required: false
+        type: string
+      golangci_lint_cache_path:
+        description: 'Path to golangci-lint cache on runner'
+        required: false
+        type: string
+    secrets: {}

Then set least-privilege permissions at the workflow level (outside the selected range; add near the top-level keys):

permissions:
  contents: read

If you want, I can propagate the same pattern to all reusable workflows in this PR and wire inputs from the new orchestrator.


🏁 Script executed:

#!/bin/bash
# Inspect the presence and context of workflow_call, inputs, secrets, and permissions in lint.yml
echo "---- snippet around workflow_call ----"
rg -n "workflow_call" -A5 -B5 .github/workflows/lint.yml || true

echo -e "\n---- top of lint.yml (first 20 lines) ----"
sed -n '1,20p' .github/workflows/lint.yml

Length of output: 764


Formalize reusable workflow inputs/secrets and enforce least-privilege permissions

This workflow currently exposes workflow_call without any declared inputs, secrets, or explicit permissions. Defining them makes the contract clearer for callers and tightens security.

• File: .github/workflows/lint.yml
• Location: around lines 3–5 (the on: workflow_call: block)
• Also add a top-level permissions section (immediately under name:)

Suggested changes:

 name: Lint
+
+permissions:
+  contents: read
 on:
   workflow_call:
+    inputs:
+      go_version:
+        description: 'Go toolchain version (mise will resolve)'
+        required: false
+        type: string
+      golangci_lint_cache_path:
+        description: 'Path to golangci-lint cache on runner'
+        required: false
+        type: string
+    secrets: {}
 jobs:
   lint:
     runs-on: ubuntu-latest
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
on:
push:
workflow_call:
name: Lint
permissions:
contents: read
on:
workflow_call:
inputs:
go_version:
description: 'Go toolchain version (mise will resolve)'
required: false
type: string
golangci_lint_cache_path:
description: 'Path to golangci-lint cache on runner'
required: false
type: string
secrets: {}
jobs:
lint:
runs-on: ubuntu-latest
🤖 Prompt for AI Agents
.github/workflows/lint.yml around lines 3 to 5: the workflow_call trigger is
declared with no explicit inputs, secrets or permissions; update the on:
workflow_call block to declare named inputs and any required secrets (with types
and required: true/false) that callers must provide, and add a top-level
permissions section immediately under the name: key that grants only the minimal
rights needed (for example set contents: read, actions: read, pull-requests:
write or as appropriate), ensuring each permission is the least-privilege
option; also document default values and required flags for inputs so callers
have a clear contract.

Comment on lines 3 to 5
on:
push:
workflow_call:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reusable workflow conversion is fine; add inputs and restrict permissions.

Let callers customize globs and keep permissions minimal.

 on:
-  workflow_call:
+  workflow_call:
+    inputs:
+      globs:
+        description: 'Markdown file globs to lint (newline separated)'
+        required: false
+        type: string
+    secrets: {}

Add (outside selected range):

permissions:
  contents: read
🤖 Prompt for AI Agents
In .github/workflows/markdownlint.yml around lines 3 to 5, the reusable workflow
currently only declares workflow_call; update it to accept configurable glob
inputs and restrict permissions: add a workflow_call.inputs block exposing at
least a globs input (string or array) with a sensible default so callers can
customize file globs, and add a top-level permissions block (outside the shown
lines) setting contents: read to minimize token scope. Ensure inputs are
documented in the workflow and referenced where the lint job reads file
patterns.

@denis256 denis256 merged commit 55fb64d into main Aug 15, 2025
119 of 121 checks passed
@denis256 denis256 deleted the chore/cleaning-up-ci branch August 15, 2025 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants